<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>Git基本使用与协作开发学习 | LenlBlog</title><meta name="author" content="Lenl,lenl412@163.com"><meta name="copyright" content="Lenl"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><meta name="description" content="记录一下Git基本的使用与团队协作开发的一些技巧">
<meta property="og:type" content="article">
<meta property="og:title" content="Git基本使用与协作开发学习">
<meta property="og:url" content="https://lienle.gitee.io/notes/GitLearn/index.html">
<meta property="og:site_name" content="LenlBlog">
<meta property="og:description" content="记录一下Git基本的使用与团队协作开发的一些技巧">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png">
<meta property="article:published_time" content="2023-05-05T02:43:30.000Z">
<meta property="article:modified_time" content="2023-05-06T08:34:55.058Z">
<meta property="article:author" content="Lenl">
<meta property="article:tag" content="Git">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png"><link rel="shortcut icon" href="/img/lenl.png"><link rel="canonical" href="https://lienle.gitee.io/notes/GitLearn/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><meta name="baidu-site-verification" content="codeva-6HME93uF43"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?629608ec0c773bd9f96cb72389693ab9";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"top_n_per_article":1,"unescape":false,"languages":{"hits_empty":"找不到您查询的内容：${query}","hits_stats":"共找到 ${hits} 篇文章"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50,"languages":{"author":"作者: Lenl","link":"链接: ","source":"来源: LenlBlog","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: true,
  islazyload: true,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  }
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Git基本使用与协作开发学习',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-05-06 16:34:55'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
    win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      if (id) link.id = id
      link.onerror = reject
      link.onload = link.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        link.onload = link.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(link)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', 'ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script></head><body><!--include ./fullpage-loading.pug--><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="wizard-scene"><div class="wizard-objects"><div class="wizard-square"></div><div class="wizard-circle"></div><div class="wizard-triangle"></div></div><div class="wizard"><div class="wizard-body"></div><div class="wizard-right-arm"><div class="wizard-right-hand"></div></div><div class="wizard-left-arm"><div class="wizard-left-hand"></div></div><div class="wizard-head"><div class="wizard-beard"></div><div class="wizard-face"><div class="wizard-adds"></div></div><div class="wizard-hat"><div class="wizard-hat-of-the-hat"></div><div class="wizard-four-point-star --first"></div><div class="wizard-four-point-star --second"></div><div class="wizard-four-point-star --third"></div></div></div></div></div></div><script>const preloader = {
  endLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = 'hidden';
    document.getElementById('loading-box').classList.remove("loaded")
  }
}

preloader.initLoading()
window.addEventListener('load',()=> { preloader.endLoading() })
//避免加载时间过长
setTimeout(function(){preloader.endLoading();}, 3000);

if (false) {
  document.addEventListener('pjax:send', () => { preloader.initLoading() })
  document.addEventListener('pjax:complete', () => { preloader.endLoading() })
}</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "/img/hexo_loading.gif" data-lazy-src="/img/lenl.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">25</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 存档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 分享</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/collect/"><i class="fa-fw fas fa-book"></i><span> 大佬们の干货</span></a></li><li><a class="site-page child" href="/resources/"><i class="fa-fw fab fa-dropbox"></i><span> 屯屯鼠の资源</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg fixed" id="page-header" style="background-image: url('https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png')"><nav id="nav"><span id="blog-info"><a href="/" title="LenlBlog"><img class="site-icon" src= "/img/hexo_loading.gif" data-lazy-src="/img/lenl.png"/><span class="site-name">LenlBlog</span></a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search" href="javascript:void(0);"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 存档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 分享</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/collect/"><i class="fa-fw fas fa-book"></i><span> 大佬们の干货</span></a></li><li><a class="site-page child" href="/resources/"><i class="fa-fw fab fa-dropbox"></i><span> 屯屯鼠の资源</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Git基本使用与协作开发学习</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-05-05T02:43:30.000Z" title="发表于 2023-05-05 10:43:30">2023-05-05</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-05-06T08:34:55.058Z" title="更新于 2023-05-06 16:34:55">2023-05-06</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E5%AD%A6%E4%B9%A0%E7%BB%8F%E9%AA%8C/">学习经验</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">5k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>18分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Git基本使用与协作开发学习"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span><span class="post-meta-separator">|</span><span class="post-meta-commentcount"><i class="far fa-comments fa-fw post-meta-icon"></i><span class="post-meta-label">评论数:</span><a href="/notes/GitLearn/#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/notes/GitLearn/" itemprop="commentCount"><i class="fa-solid fa-spinner fa-spin"></i></span></a></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><div class="note info simple"><p>在以往的git使用中，由于基本上是单人开发，而且项目比较小，因此仅仅是将其作为一个备份防丢失的远程库，存放代码文件，对其使用进阶技巧和功能知之甚少也很少关注。</p>
<p>随着项目做的比较大，需要协作开发，想推进使用git与团队进行协作开发，但囿于自身掌握程度偏低，没有顺利带领团队推进使用git的协作。</p>
<p>因此，打算再再再一次系统地、广泛地学习git使用技巧，一方面为了推进团队的协作开发，另一方面为了之后能够在git上和大佬们一起玩代码。</p>
</div>
<p>git可以在一些优秀的博客文章中学习，很多。</p>
<p>关于github 的学习最好的方法还是阅读又细又全的官方文档：<a target="_blank" rel="noopener" href="https://docs.github.com/zh">GitHub Docs</a></p>
<p>这里我从一个协作开发实战的教学视频中进行一些总结，仅供个人参考备忘。</p>
<h2 id="基本概念">基本概念</h2>
<p>git : 分布式 版本控制 软件。</p>
<p>进步：多文件版本 – 本地单文件版本控制 – 集中式版本控制(SVN) – 分布式版本控制</p>
<h2 id="基本使用">基本使用</h2>
<h3 id="初始操作">初始操作</h3>
<ol>
<li class="lvl-3">
<p>进入要管理的目录</p>
</li>
<li class="lvl-3">
<p>初始化：<code>git init</code></p>
</li>
<li class="lvl-3">
<p>状态查看： <code>git status</code></p>
<ul class="lvl-2">
<li class="lvl-5">红色：新增文件/修改了的原老文件</li>
<li class="lvl-5">绿色：git已经管理了该文件，但尚未生成版本</li>
<li class="lvl-5">生成了版本的文件不再显示</li>
</ul>
</li>
<li class="lvl-3">
<p>将文件管理起来：<code>git add .</code> 或 <code>git add xxx</code></p>
</li>
<li class="lvl-3">
<p>个人信息配置(用户名、邮箱)：</p>
<ul class="lvl-2">
<li class="lvl-5"><code>git conig --global user.name &quot;xxx&quot;</code></li>
<li class="lvl-5"><code>git config --global user.email &quot;xxx@xx.com&quot;</code></li>
</ul>
</li>
<li class="lvl-3">
<p>提交，生成版本：<code>git commit -m &quot;v1 description&quot;</code></p>
</li>
<li class="lvl-3">
<p>查看提交记录：<code>git log</code></p>
</li>
</ol>
<h3 id="git三大区域">git三大区域</h3>
<table>
<thead>
<tr>
<th>工作区</th>
<th>暂存区</th>
<th>版本库</th>
</tr>
</thead>
<tbody>
<tr>
<td>|已管理(绿色)|新增/修改(红色)|     —&gt;(git add .)</td>
<td>—&gt;(git commit -m “”)</td>
<td>生成版本</td>
</tr>
</tbody>
</table>
<p>详细如图：</p>
<p><a target="_blank" rel="noopener" href="https://z4a.net/image/VmvrOI"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/05/05/git.md.png" alt="git三大区域及关系示意图"></a></p>
<h3 id="git回滚">git回滚</h3>
<h4 id="场景1-回滚">场景1 回滚</h4>
<p>当前已提交了v1，v2两个版本，但此时需要重新回滚到v1版本：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 查询提交日志</span></span><br><span class="line">git <span class="built_in">log</span></span><br><span class="line"><span class="comment">#结果</span></span><br><span class="line">commit f5ca8858834f603402fcd49c363ba17ae5356969 (HEAD -&gt; master)</span><br><span class="line">Author: LNL &lt;2570358917@qq.com&gt;</span><br><span class="line">Date:   Fri May 5 13:44:42 2023 +0800</span><br><span class="line"></span><br><span class="line">    v2</span><br><span class="line"></span><br><span class="line">commit 9b12418d47c2c1712d0ad6cfa8b0cb770ed0cfb4</span><br><span class="line">Author: LNL &lt;2570358917@qq.com&gt;</span><br><span class="line">Date:   Fri May 5 13:44:07 2023 +0800</span><br><span class="line"></span><br><span class="line">    v1</span><br></pre></td></tr></table></figure>
<p>得到的结果可以得到两个提交版本的id，其中v1版本id为 <code>9b12418d47c2c1712d0ad6cfa8b0cb770ed0cfb4</code></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 通过版本id回到v1版本</span></span><br><span class="line">git reset --hard 9b12418d47c2c1712d0ad6cfa8b0cb770ed0cfb4</span><br><span class="line"><span class="comment"># 结果</span></span><br><span class="line">HEAD is now at 9b12418 v1</span><br></pre></td></tr></table></figure>
<p>此时文件的版本已经回到了v1。</p>
<h4 id="场景2-回滚再恢复">场景2 回滚再恢复</h4>
<p>如果已经回滚到了v1,但是此时又因为某些原因发现不用回滚，需要再恢复到v2版本：</p>
<p>此时再执行 <code>git log</code> 会发现只有 v1 的一个版本提交记录。所以需要查询所有历史版本</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 查询所有历史提交日志</span></span><br><span class="line">git reflog</span><br><span class="line"><span class="comment"># 结果</span></span><br><span class="line">9b12418 (HEAD -&gt; master) HEAD@&#123;0&#125;: reset: moving to 9b12418d47c2c1712d0ad6cfa8b0cb770ed0cfb4</span><br><span class="line">f5ca885 HEAD@&#123;1&#125;: commit: v2</span><br><span class="line">9b12418 (HEAD -&gt; master) HEAD@&#123;2&#125;: commit (initial): v1</span><br></pre></td></tr></table></figure>
<p>此时再使用 <code>git reset</code> 回到v2版本</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 恢复回滚前的版本</span></span><br><span class="line">git reset --hard f5ca885</span><br><span class="line"><span class="comment"># 结果</span></span><br><span class="line">HEAD is now at f5ca885 v2</span><br></pre></td></tr></table></figure>
<p>关于 <code>git reset</code> 命令的详细使用，可以参照菜鸟教程：<a target="_blank" rel="noopener" href="https://www.runoob.com/git/git-reset.html">git reset 命令 | 菜鸟教程 (runoob.com)</a></p>
<h4 id="命令小总结">命令小总结</h4>
<p>关于命令的总结，可以参考这篇文章：<a target="_blank" rel="noopener" href="https://www.wolai.com/dewjjj/tCYEeiA6Gb5Yyrdm4PN15g">Git命令总结</a></p>
<ol>
<li class="lvl-3">
<p>设置git默认选项</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git config --global user.email <span class="string">&quot;[your email address]&quot;</span></span><br><span class="line">git config --global user.name <span class="string">&quot;[your nickname]&quot;</span> </span><br><span class="line">git config -l</span><br><span class="line"><span class="built_in">history</span></span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-3">
<p>git简单管理文件</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git init</span><br><span class="line">git status</span><br><span class="line">git add [filename.filetype] <span class="comment"># 添加到缓存区</span></span><br><span class="line">git add .</span><br><span class="line">git commit</span><br><span class="line">git commit -m <span class="string">&quot;[version name]&quot;</span></span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-3">
<p>文件与版本相关操作</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">log</span> <span class="comment"># 查看提交日志</span></span><br><span class="line">git reflog <span class="comment"># 查看所有历史提交日志</span></span><br><span class="line">git checkout -- [filename] <span class="comment"># 将文件从修改状态改回未修改状态</span></span><br><span class="line">git reset HEAD [filename] <span class="comment"># 将文件从暂存区返回到工作区</span></span><br><span class="line">git reset --hard [版本<span class="built_in">id</span>] <span class="comment"># 回滚</span></span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="分支开发">分支开发</h3>
<p>主干线：master</p>
<h4 id="场景">场景</h4>
<p>当开发新功能v3过程中时，主分支master原代码v2中有bug需要修复。此时合理方式是再master上开dev分支开发v3，在修复v2时创建新的分支bug，进行修复生成v4，bug并合并到master得到v5，修复完毕后回到dev分支v3继续开发新功能。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 当前分支</span></span><br><span class="line">git branch</span><br><span class="line"><span class="comment"># 创建新分支 dev</span></span><br><span class="line">git branch dev</span><br><span class="line"><span class="comment"># 切换分支 dev</span></span><br><span class="line">git checkout dev</span><br><span class="line"><span class="comment"># 创建并切换</span></span><br><span class="line">git checkout -b dev</span><br></pre></td></tr></table></figure>
<p>添加v3内容后；</p>
<p>创建bug分支，修复bug生成v4版本</p>
<p>将bug分支合并到master</p>
<p>bug分支已无作用，删除bug分支</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 回到master分支</span></span><br><span class="line">git checkout master</span><br><span class="line"><span class="comment"># 合并bug分支</span></span><br><span class="line">git merge bug</span><br><span class="line"><span class="comment"># 删除bug分支</span></span><br><span class="line">git branch -d bug</span><br></pre></td></tr></table></figure>
<p>回到dev分支，开发完v3新功能剩下的部分，变成v5版本</p>
<p>此时如果直接回到master分支直接合并则会产生冲突，因为此时dev分支上的bug还处于未修复状态</p>
<p>冲突会将内容都展示在文件里，需要手动解决冲突。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 合并dev</span></span><br><span class="line">get merge dev</span><br><span class="line"><span class="comment"># 产生冲突的结果</span></span><br><span class="line">CONFLICT (content): Merge conflict <span class="keyword">in</span> 123.txt</span><br><span class="line">Automatic merge failed; fix conflicts and <span class="keyword">then</span> commit the result.</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">## 手动修复冲突前：</span><br><span class="line"></span><br><span class="line">v1</span><br><span class="line">&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD</span><br><span class="line">v2  v4--修复了bug(与v3不冲突)</span><br><span class="line">=======</span><br><span class="line">v2</span><br><span class="line"></span><br><span class="line">v3 dev modify finished</span><br><span class="line">&gt;&gt;&gt;&gt;&gt;&gt;&gt; dev</span><br><span class="line"></span><br><span class="line">## 手动修复冲突后：</span><br><span class="line"></span><br><span class="line">v1</span><br><span class="line">v2  v4--修复了bug(与v3不冲突)</span><br><span class="line"></span><br><span class="line">v3 dev modify finished</span><br></pre></td></tr></table></figure>
<p>修复后master分支的状态为 <code>master|MERGING</code></p>
<p>此时直接 add 和 commit 即可。</p>
<h4 id="命令小总结-2">命令小总结</h4>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 查看[创建]分支</span></span><br><span class="line">git branch [新分支名]</span><br><span class="line"><span class="comment"># 切换分支</span></span><br><span class="line">git checkout 分支名</span><br><span class="line"><span class="comment"># 分支合并 （可能产生冲突）</span></span><br><span class="line">git merge 要合并的分支 <span class="comment">#注意要切换分支再合并，当前在哪个分支，哪个分支就是吸收者</span></span><br><span class="line"><span class="comment"># 删除分支</span></span><br><span class="line">git branch -d 分支名称</span><br></pre></td></tr></table></figure>
<h4 id="简单git工作流">简单git工作流</h4>
<p>分支至少有2个</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-master-主分支(正式/稳定/线上 版本)</span><br><span class="line">	--dev (开发版本 代码开发在此分支)</span><br></pre></td></tr></table></figure>
<h3 id="GitHub代码托管">GitHub代码托管</h3>
<h4 id="代码托管到github">代码托管到github</h4>
<blockquote>
<p>gitlab工具可以自搭建git代码托管平台</p>
</blockquote>
<p>首先注册github账号，在Repository创建一个自己的仓库 <code>GitLearn</code> 来进行测试。</p>
<p>本地添加该仓库并推送</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git remote add origin https://github.com/vimianma/GitLearn.git</span><br><span class="line">git push -u origin master</span><br></pre></td></tr></table></figure>
<p>初次可能会需要输入github的账号密码，在一些情况下如关闭了SSL的时候还会报错</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">fatal: unable to access &#x27;https://github.com/vimianma/GitLearn.git/&#x27;: OpenSSL SSL_read: Connection was reset, errno 10054</span><br></pre></td></tr></table></figure>
<p>本人由于配置了Gitee和GitHub两个代码库，但当初注册时两端用户名等都不一样，两边都要配置ssh，这里记录一下解决过程：<p id="sshLogin">SSH免密登录实现方式</p></p>
<ol>
<li class="lvl-3">
<p>生成gitee和github的公钥</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 生成gitee公钥</span></span><br><span class="line">ssh-keygen -t ed25519 -f ~/.ssh/id_rsa_gitee -C “123456@qq.com”</span><br><span class="line"><span class="comment"># 生成github公钥</span></span><br><span class="line">ssh-keygen -t ed25519 -f ~/.ssh/id_rsa_github -C “654321@qq.com”</span><br></pre></td></tr></table></figure>
<p>采用无密码方式，要求输入密码时直接回车即可</p>
</li>
<li class="lvl-3">
<p>在 <code>C:/用户/用户名/.ssh</code> 下找到 <code>id_rsa_gitee.pub</code> 和 <code>id_rsa_github.pub</code> ,将里面的值复制到对应平台的SSH公钥设置处。名称可以随意起。</p>
</li>
<li class="lvl-3">
<p>本地配置公钥对</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 在本地创建config</span></span><br><span class="line"><span class="built_in">touch</span> ~/.ssh/config</span><br></pre></td></tr></table></figure>
<p>在config中输入以下内容：</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#Default gitHub user Self</span><br><span class="line">Host github.com</span><br><span class="line">    HostName github.com</span><br><span class="line">    User [Username]</span><br><span class="line">    IdentityFile ~/.ssh/id_rsa_github</span><br><span class="line"></span><br><span class="line"># gitee</span><br><span class="line">Host gitee.com</span><br><span class="line">    Port 22</span><br><span class="line">    HostName gitee.com</span><br><span class="line">    User [Username]</span><br><span class="line">    IdentityFile ~/.ssh/id_rsa_gitee</span><br></pre></td></tr></table></figure>
<p>测试是否成功：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh -T git@gitee.com</span><br><span class="line">ssh -T git@github.com</span><br></pre></td></tr></table></figure>
<p>显示 <code>Hi xxx! You've successfully authenticated,...</code> 即代表成功</p>
</li>
</ol>
<p>好了回到正题，这是我们将master分支推送到了远程仓库，但没有其他分支，需要将其他分支也推送进去。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git push -u origin dev</span><br></pre></td></tr></table></figure>
<h4 id="代码clone到本地两-多-地开发">代码clone到本地两(多)地开发</h4>
<p>在另外一个目录 home 中，我们将远程仓库clone下来。这里我们将最初的库简称为cloud。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/vimianma/GitLearn.git</span><br><span class="line"><span class="comment"># clone下来的内部已实现 git remote add origin 远程仓库地址</span></span><br></pre></td></tr></table></figure>
<p>可以发现clone下来的代码用 <code>git branch</code> 命令只能看到master分支，但我们仍然可以直接 <code> git checkout dev</code> 直接切换到dev分支。</p>
<p>此时我们应该在dev分支上做开发。但是需要使dev分支和master分支保持最新的一致。而我们之前的例子中dev分支缺少master分支中的部分内容，所以此时可以将master分支合并到dev分支</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git branch dev</span><br><span class="line">git merge master</span><br></pre></td></tr></table></figure>
<p>在home中进行新的开发后提交到dev分支，并push到远程的dev分支上。</p>
<p>再打开cloud时，dev中没有home开发的新代码，需要使用pull更新一下。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># cloud 库</span></span><br><span class="line">git branch dev</span><br><span class="line">git pull origin dev</span><br></pre></td></tr></table></figure>
<p>这样以后，在cloud开发的新代码，在home中也可以通过同样的方式进行同步。</p>
<p>开发完毕要上线后cloud：</p>
<p>​	回到 master 分支，合并dev，push。将dev也push一下。</p>
<p>这时home也需要pull一下master。</p>
<h4 id="冲突情景">冲突情景</h4>
<p>当cloud的修改未提交到github，home又做了新的更改并提交到了github。回到cloud进行开发时，需要拉取github的更新，并需要合并cloud的更改，这可能会产生冲突。</p>
<p>在cloud执行 <code>git pull origin dev</code> 产生冲突后，按之前提到的方式手动解决冲突。</p>
<p>继续进行开发后推送即可。</p>
<div class="note warning simple"><p><code>git pull origin dev</code> 相当于 <code>git fetch origin dev</code> 与 <code>git merge origin/dev</code> 两个命令的集合</p>
</div>
<h4 id="使提交记录简洁——git-rebase-变基">使提交记录简洁——git rebase (变基)</h4>
<p><strong>场景1：使多个提交记录整合为一个提交记录</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 方式1 使用版本号 表示指定版本号直到目前的提交合并为一个</span></span><br><span class="line">git rebase -i [版本号]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 方式2 指定数量 从当前开始找最近的n条记录合并</span></span><br><span class="line">git rebase -i HEAD~n</span><br></pre></td></tr></table></figure>
<p>执行后会出现vim</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">pick id1 comment1</span><br><span class="line">pick id2 comment2</span><br><span class="line">pick id3 comment3</span><br></pre></td></tr></table></figure>
<p>此时按 <code>i</code> ，然后将其改为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">pick id1 comment1</span><br><span class="line">s id2 comment2</span><br><span class="line">s id3 comment3</span><br></pre></td></tr></table></figure>
<p>s意为合并到上一个版本，因此下面两个将合并到id1。</p>
<p>保存之后会出现另一个vim，意为整合后的提交comment</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># This is a combination of 3 commits.</span><br><span class="line"># This is the 1st commit message:</span><br><span class="line"></span><br><span class="line">v2</span><br><span class="line"></span><br><span class="line"># This is the commit message #2:</span><br><span class="line"></span><br><span class="line">v3</span><br><span class="line"></span><br><span class="line"># This is the commit message #3:</span><br><span class="line"></span><br><span class="line">v4</span><br></pre></td></tr></table></figure>
<p>这部分可自行编辑。</p>
<p>保存后，提交记录将会整合在一起。</p>
<div class="note warning simple"><p>合并记录时，最好合并已push到github的记录。这样会产生很多不必要的麻烦，而且会使提交记录混乱。</p>
</div>
<p><strong>场景2：使分支的提交记录合并插入到主干分支的提交记录成为其一部分</strong></p>
<p>当dev更改提交后，切换到master进行更改提交，此时两个分支不一致。</p>
<p>可以使用 <code>git merge</code> 将dev合并到master，但运行 <code>git log --graph</code> 可以通过图示发现dev的那次提交仍在dev的分支上而不是master的分支。</p>
<p>另：<code>git log --graph --pretty=format:&quot;%h %s&quot;</code> 能够美化优雅地展示提交日志。</p>
<p>使用git rebase使分支的提交记录合并插入到主干分支的提交记录成为其一部分：</p>
<p>切回dev分支，执行rebase命令：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git rebase master</span><br></pre></td></tr></table></figure>
<p>再切回master分支，merge dev</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git checkout master</span><br><span class="line">git merge dev</span><br></pre></td></tr></table></figure>
<p>此时再查看 <code>git log --graph</code> 可以看到master的提交记录不再有分支，dev的提交记录作为一部分插入了master分支。</p>
<p><strong>场景3：pull冲突问题解决</strong></p>
<p>之前当github上代码与本地有冲突时，执行git pull 会产生冲突，分叉。</p>
<p>此时，先执行 <code>git fetch origin dev</code> 将代码拉到本地，然后执行 <code>git rebase origin/dev</code></p>
<p>这样就不会产生分叉。</p>
<div class="note warning simple"><p>执行 rebase 产生冲突时，会进行提示，需要先解决冲突</p>
<p>完毕后可根据提示进行操作<code>git add</code></p>
<p>然后执行 <code>git rebase --continue</code> 继续</p>
</div>
<h4 id="beyond-compare-快速解决冲突">beyond compare 快速解决冲突</h4>
<ol>
<li class="lvl-3">
<p>安装软件</p>
<p>下载beyond compare软件，这个软件是收费的，可以下载绿色版或者其他类似功能的软件。</p>
</li>
<li class="lvl-3">
<p>再git中添加配置</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># --local 只对本次项目有效 --global 全局有效</span></span><br><span class="line">git config --<span class="built_in">local</span> merge.tool bc</span><br><span class="line">git config --<span class="built_in">local</span> mergetool.path <span class="string">&#x27;[软件安装路径]&#x27;</span></span><br><span class="line">git config --global mergetool.bc.cmd <span class="string">&quot;\&quot;[软件安装路径]\&quot; \&quot;\$LOCAL\&quot; \&quot;\$REMOTE\&quot; \&quot;\$BASE\&quot; \&quot;\$MERGED\&quot;&quot;</span></span><br><span class="line"><span class="comment"># 不保留原文件</span></span><br><span class="line">git config --<span class="built_in">local</span> mergetool.keepBackup <span class="literal">false</span> </span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-3">
<p>应用beyond compare解决冲突</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git mergetool</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-3">
<p>在弹出的界面上解决冲突。</p>
</li>
</ol>
<h4 id="命令总结">命令总结</h4>
<ul class="lvl-0">
<li class="lvl-2">
<p>添加远程连接（别名）</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git remote add origin 地址</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-2">
<p>推送代码</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git push origin dev</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-2">
<p>下载代码</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> 地址</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-2">
<p>拉取代码</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git pull origin dev</span><br><span class="line"><span class="comment">#等价于</span></span><br><span class="line">git fetch origin dev</span><br><span class="line">git merge origin/dev</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-2">
<p>保持代码提交整洁（变基）</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git rebase 分支</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-2">
<p>记录图形显示</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">log</span> --graph --pretty=format:<span class="string">&quot;%h %s&quot;</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="git多人协作">git多人协作</h2>
<p>以上操作基本上都是单人在多地使用git做版本控制，但多人协作并非仅仅如此。</p>
<h3 id="多人协作开发工作流（git-flow）">多人协作开发工作流（git flow）</h3>
<ol>
<li class="lvl-3">
<p>dev分支从master分支分出一个开发分支，假设A、B加入协作开发，则各自需要开一个分支，从dev分支拆出A、B分支。</p>
</li>
<li class="lvl-3">
<p>假如A分支开发完毕，需要合并到dev分支，需要进行代码Review，控制是否进行合并。</p>
</li>
<li class="lvl-3">
<p>当多个dev都开发完毕后，再建一个release分支进行测试，完善文档，修改bug等。</p>
</li>
<li class="lvl-3">
<p>测试完毕后才能上线。release分支做的更改要合并到dev分支，使其同步。</p>
</li>
<li class="lvl-3">
<p>此时A、B分支已经无用，可以删除。</p>
</li>
</ol>
<blockquote>
<p>非正规流程可能会忽略release和代码review</p>
</blockquote>
<h3 id="多人协同开发功能">多人协同开发功能</h3>
<h4 id="模拟多人协作场景">模拟多人协作场景</h4>
<p>首先创建项目目录 <code>nultiPerson\dbhot</code> ,执行下列命令搭建环境：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 初始化git</span></span><br><span class="line">git init</span><br><span class="line"><span class="comment"># 创建app文件</span></span><br><span class="line"><span class="built_in">touch</span> app.py</span><br><span class="line"><span class="comment"># 提交</span></span><br><span class="line">git add .</span><br><span class="line">git commit -m <span class="string">&quot;初始化&quot;</span></span><br></pre></td></tr></table></figure>
<p>然后创建项目：</p>
<p>方式一是在github创建项目仓库，然后再settings的collaborators邀请他人加入。</p>
<p>方式二是先创建一个组织，然后在组织里创建项目仓库。（创建组织仓库有利于多项目统一管理）</p>
<p>创建完毕后，添加远程仓库并进行推送。</p>
<h4 id="版本标签命名">版本标签命名</h4>
<p>由于版本名称太长，需要使用tag自定义版本名称。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># -a 轻量标签</span></span><br><span class="line">git tag -a v1 -m <span class="string">&quot;第一版&quot;</span></span><br><span class="line"><span class="comment"># 将标签推送到github</span></span><br><span class="line">git push origin --tags</span><br></pre></td></tr></table></figure>
<blockquote>
<p>该命令更多详细可见 <a target="_blank" rel="noopener" href="https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%89%93%E6%A0%87%E7%AD%BE">Git - 打标签 (git-scm.com)</a></p>
</blockquote>
<p>版本命名提交到github后，可以在tags下看到，并且release也会生成对应的版本发布，可以进行下载。</p>
<h4 id="邀请成员">邀请成员</h4>
<p>先创建一个dev分支 <code>git checkout -b dev</code> 、<code>git push origin dev</code></p>
<p>将成员注册的账号邀请进github的组织。</p>
<p>在组织的settings – member privileges对成员的基本权限进行控制（对所有项目起效）</p>
<p>在项目的settings – Collaborators and teams 可以针对当前项目邀请成员并对成员的权限进行管理</p>
<h4 id="成员模拟">成员模拟</h4>
<p>在本地创建 <code>brother</code> 目录，运行 <code>git clone xxx</code> 将组织里项目的代码拉带本地。</p>
<p>切换到dev分支(要从dev分支拆出分支)，创建自己的新分支（加入以功能命名为ddz）</p>
<p>brother开发ddz功能并push到github的ddz分支。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">这里记一个突发情况：</span><br><span class="line">由于github一直被墙，使用梯子也会时断时连，因此参考网上的方法配置了代理：</span><br><span class="line">git config --global http.proxy=&quot;127.0.0.1:xxxx&quot;</span><br><span class="line">git config --global https.proxy=&quot;127.0.0.1:xxxx&quot;</span><br><span class="line">之后发现仍然没什么效果，遂取消代理</span><br><span class="line">git config --global unset http.proxy</span><br><span class="line">git config --global unset https.proxy</span><br><span class="line">但是之后再执行git push 一直报错端口 xxxx connect refused</span><br><span class="line">经过蛮久的debug发现原来是之前配置代理，不知道是复制粘贴错误还是其他什么原因，配置变成了 http.https://github.com.proxy，因此怎么取消都没取消掉这一条，而且它竟然还起作用了！</span><br><span class="line">使用 git config --list | grep proxy 查到的</span><br><span class="line">取消那个错误前缀后，恢复正常。</span><br></pre></td></tr></table></figure>
<h4 id="代码review">代码review</h4>
<p>使用github的 <code>pull request</code> 实现。</p>
<p>首先这需要在github配置项目。来到项目<code>settings</code>-<code>Branches</code>-<code>Add branch protection rule</code> 在这里输入分支名称，勾选 <code>Require a pull request before merging</code> ，可以设定需要多少人review (这里选择1)，一般dev分支和master分支都需要这样进行。</p>
<p>然后由brother登录账号，来到仓库的 <code>Pull Request</code> 提交一个 pull request ，请求将自己之前开发的ddz功能分支合并到dev分支。</p>
<p><a target="_blank" rel="noopener" href="https://z4a.net/image/VmYUlk"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/05/06/pullrequest.md.png" alt="github提交Pull Request 示例图"></a></p>
<p>此时库管理员可以看到一个pull request，点开后切换到<code>files changed</code>可以展开对其进行review。</p>
<p>review完成后，回来 <code>conversation</code>  点击 <code>merge pull request</code> 然后 confirm ，即可完成合并。</p>
<p>已经closed 的pull request 会提示 <code>Pull request successfully merged and closed</code> 并且右侧会有一个按钮 <code>delete branch</code> 即分支已经合并，可以删除。</p>
<p>合并后，管理员本地可以通过 <code>git pull origin dev</code> 同步拉取更新本地代码。</p>
<h4 id="测试预发布">测试预发布</h4>
<p>由管理员创建 <code>release</code> 分支，并提交到github，此时测试人员可以拉取并进行测试（这里一般不会轻易改代码）。</p>
<p>这里测试或小修改完成后，可再次提交一个 <code>release</code> --&gt; <code>master</code> 的pull request 。在提交 pull request 时可以指定 <code>Reviewer</code> 进行review。合并后，库中master即为发布版本。</p>
<p>此时，在本地可以进行dev合并release、删除release分支、pull master分支，然后给这个master打个tag，表示这是所发行的另一版本v2。</p>
<div class="note warning simple"><p>多人协作pull request合并时也可能会产生冲突，此时像前面那样把冲突解决，然后继续合并即可。</p>
</div>
<h3 id="给开源项目贡献代码">给开源项目贡献代码</h3>
<ol>
<li class="lvl-3">
<p>先fork源代码</p>
<p>即，将他人的源代码拷贝到自己的远程仓库。</p>
</li>
<li class="lvl-3">
<p>在自己仓库修改源代码</p>
<p>本地修改后提交到自己的远程仓库。</p>
</li>
<li class="lvl-3">
<p>给源代码作者提交 修复bug的申请（在自己的仓库 new pull request）</p>
<p>这里选择从自己的master合并到对方的master</p>
</li>
</ol>
<h2 id="git其他拓展">git其他拓展</h2>
<h3 id="配置">配置</h3>
<p>通过命令行进行配置</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 1.项目配置文件 项目/.git/config</span></span><br><span class="line">git config --<span class="built_in">local</span> user.name <span class="string">&#x27;xxx&#x27;</span></span><br><span class="line">git config --<span class="built_in">local</span> user.email <span class="string">&#x27;xxxx@xx.com&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2.全局配置文件 </span></span><br><span class="line"><span class="comment"># linux: ~/.gitconfig   windows: C:/用户/[用户名]/.gitconfig</span></span><br><span class="line">git config --global user.name <span class="string">&#x27;xxx&#x27;</span></span><br><span class="line">git config --global user.email <span class="string">&#x27;xxxx@xx.com&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3.系统配置文件 一般不会用到</span></span><br><span class="line"><span class="comment"># linux: /etc/.gitconfig  需要root权限</span></span><br><span class="line">git config --system user.name <span class="string">&#x27;xxx&#x27;</span></span><br><span class="line">git config --system user.email <span class="string">&#x27;xxxx@xx.com&#x27;</span></span><br></pre></td></tr></table></figure>
<p>应用场景</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 用户名密码</span></span><br><span class="line">git config --[area] user.name <span class="string">&#x27;xxx&#x27;</span></span><br><span class="line">git config --[area] user.email <span class="string">&#x27;xxxx@xx.com&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#配置冲突解决软件</span></span><br><span class="line">git config --[area] merge.tool bc</span><br><span class="line">git config --[area] mergetool.path <span class="string">&#x27;[软件安装路径]&#x27;</span></span><br><span class="line">git config --[area] mergetool.bc.cmd <span class="string">&quot;\&quot;[软件安装路径]\&quot; \&quot;\$LOCAL\&quot; \&quot;\$REMOTE\&quot; \&quot;\$BASE\&quot; \&quot;\$MERGED\&quot;&quot;</span></span><br><span class="line">git config --[area] mergetool.keepBackup <span class="literal">false</span> </span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加远程地址及别名 这里相当于 --local 配置在了当前项目</span></span><br><span class="line">git remote add origin 地址</span><br></pre></td></tr></table></figure>
<h3 id="免密登录">免密登录</h3>
<ul class="lvl-0">
<li class="lvl-2">
<p>URL中体现</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">原来的地址：https://github.com/LenlOrg/dbhot.git</span><br><span class="line">修改的地址：https://用户名：密码@github.com/LenlOrg/dbhot.git</span><br><span class="line"></span><br><span class="line">git remote add origin 修改的地址 </span><br><span class="line">之后就不用再输入用户名密码</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-2">
<p>SSH实现</p>
<p>该实现方式比较便捷，实现方式在前文中已经提到了：<a href="#sshLogin">SSH方式的免密登录</a></p>
<p>不过使用ssh的地址的方式略有不同：</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">1.生成公钥和私钥（默认在~/.ssh目录下），id_rsa.pub公钥，id_rsa私钥</span><br><span class="line">	ssh-keygen</span><br><span class="line">2.拷贝公钥内容，并设置到github中去。</span><br><span class="line">3.在git本地中配置ssh地址</span><br><span class="line">	git remote add origin git@github.com:LenlOrg/dbhot.git</span><br><span class="line">4.以后使用</span><br><span class="line">	git push origin master</span><br></pre></td></tr></table></figure>
</li>
<li class="lvl-2">
<p>git自动管理凭证</p>
<p>首次输入后git会自动进行管理。</p>
</li>
</ul>
<h3 id="gitignore忽略文件">gitignore忽略文件</h3>
<p>能够告诉git在管理时忽略哪个文件。</p>
<p>如：</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#忽略a.h</span><br><span class="line">a.h</span><br><span class="line"></span><br><span class="line">#忽略以.h结尾的文件</span><br><span class="line">*.h</span><br><span class="line"></span><br><span class="line">#忽略files文件夹下的文件</span><br><span class="line">files/</span><br><span class="line"></span><br><span class="line">#a.h除外，搭配*.h即为除了a.h外以.h结尾的文件都忽略</span><br><span class="line">!a.h</span><br><span class="line"></span><br><span class="line">#排除 .docx\.docy\.docz后缀的</span><br><span class="line">*.doc[x|y|z]</span><br></pre></td></tr></table></figure>
<p>github有**<a target="_blank" rel="noopener" href="https://github.com/vimianma/gitignore">gitignore</a>** 仓库专门存放了各类语言的ignore，可供参考。</p>
<h3 id="任务管理相关">任务管理相关</h3>
<h4 id="issues">issues</h4>
<p>对项目相关疑问或讨论，提issues，可以汇总bug，新成员接收项目时有疑问也可在issues进行复盘。</p>
<p>文档以及任务管理</p>
<h4 id="wiki">wiki</h4>
<p>如果没有开启，可到Settings - Features中开启。</p>
<p>可以写对项目的详细介绍，注意事项等等，便于他人了解认识项目。</p>
<p>git的基本学习到此为止，更多的东西还是要实际使用总结经验。</p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://lienle.gitee.io">Lenl</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://lienle.gitee.io/notes/GitLearn/">https://lienle.gitee.io/notes/GitLearn/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://lienle.gitee.io" target="_blank">LenlBlog</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Git/">Git</a></div><div class="post_share"><div class="social-share" data-image="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/img/wechat.png" target="_blank"><img class="post-qr-code-img" src= "/img/hexo_loading.gif" data-lazy-src="/img/wechat.png" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="/img/alipay.png" target="_blank"><img class="post-qr-code-img" src= "/img/hexo_loading.gif" data-lazy-src="/img/alipay.png" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/notes/tips/" title="SpringBoot一些优雅的小技巧记录"><img class="cover" src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">SpringBoot一些优雅的小技巧记录</div></div></a></div><div class="next-post pull-right"><a href="/notes/electronLearn/" title="Electron学习入门笔记"><img class="cover" src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Electron学习入门笔记</div></div></a></div></nav><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src= "/img/hexo_loading.gif" data-lazy-src="/img/lenl.png" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">Lenl</div><div class="author-info__description">心有所向，日复一日，必有精进~</div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">25</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/vimianma"><i class="fab fa-github"></i><span>View me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://gitee.com/lienle" target="_blank" title="Gitee"><i class="fa-brands fa-git" style="color: #c71d23;"></i></a><a class="social-icon" href="https://github.com/vimianma" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:lenl412@163.com" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">本站意在记录个人生活中的所学所感所想所获；<br/>心有所向，日复一日，必有精进~~~<br>请多多指教~</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5"><span class="toc-number">1.</span> <span class="toc-text">基本概念</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">2.</span> <span class="toc-text">基本使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9D%E5%A7%8B%E6%93%8D%E4%BD%9C"><span class="toc-number">2.1.</span> <span class="toc-text">初始操作</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#git%E4%B8%89%E5%A4%A7%E5%8C%BA%E5%9F%9F"><span class="toc-number">2.2.</span> <span class="toc-text">git三大区域</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#git%E5%9B%9E%E6%BB%9A"><span class="toc-number">2.3.</span> <span class="toc-text">git回滚</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%9C%BA%E6%99%AF1-%E5%9B%9E%E6%BB%9A"><span class="toc-number">2.3.1.</span> <span class="toc-text">场景1 回滚</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%9C%BA%E6%99%AF2-%E5%9B%9E%E6%BB%9A%E5%86%8D%E6%81%A2%E5%A4%8D"><span class="toc-number">2.3.2.</span> <span class="toc-text">场景2 回滚再恢复</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%91%BD%E4%BB%A4%E5%B0%8F%E6%80%BB%E7%BB%93"><span class="toc-number">2.3.3.</span> <span class="toc-text">命令小总结</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%86%E6%94%AF%E5%BC%80%E5%8F%91"><span class="toc-number">2.4.</span> <span class="toc-text">分支开发</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%9C%BA%E6%99%AF"><span class="toc-number">2.4.1.</span> <span class="toc-text">场景</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%91%BD%E4%BB%A4%E5%B0%8F%E6%80%BB%E7%BB%93-2"><span class="toc-number">2.4.2.</span> <span class="toc-text">命令小总结</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%AE%80%E5%8D%95git%E5%B7%A5%E4%BD%9C%E6%B5%81"><span class="toc-number">2.4.3.</span> <span class="toc-text">简单git工作流</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#GitHub%E4%BB%A3%E7%A0%81%E6%89%98%E7%AE%A1"><span class="toc-number">2.5.</span> <span class="toc-text">GitHub代码托管</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81%E6%89%98%E7%AE%A1%E5%88%B0github"><span class="toc-number">2.5.1.</span> <span class="toc-text">代码托管到github</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81clone%E5%88%B0%E6%9C%AC%E5%9C%B0%E4%B8%A4-%E5%A4%9A-%E5%9C%B0%E5%BC%80%E5%8F%91"><span class="toc-number">2.5.2.</span> <span class="toc-text">代码clone到本地两(多)地开发</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%86%B2%E7%AA%81%E6%83%85%E6%99%AF"><span class="toc-number">2.5.3.</span> <span class="toc-text">冲突情景</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E6%8F%90%E4%BA%A4%E8%AE%B0%E5%BD%95%E7%AE%80%E6%B4%81%E2%80%94%E2%80%94git-rebase-%E5%8F%98%E5%9F%BA"><span class="toc-number">2.5.4.</span> <span class="toc-text">使提交记录简洁——git rebase (变基)</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#beyond-compare-%E5%BF%AB%E9%80%9F%E8%A7%A3%E5%86%B3%E5%86%B2%E7%AA%81"><span class="toc-number">2.5.5.</span> <span class="toc-text">beyond compare 快速解决冲突</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%91%BD%E4%BB%A4%E6%80%BB%E7%BB%93"><span class="toc-number">2.5.6.</span> <span class="toc-text">命令总结</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#git%E5%A4%9A%E4%BA%BA%E5%8D%8F%E4%BD%9C"><span class="toc-number">3.</span> <span class="toc-text">git多人协作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%9A%E4%BA%BA%E5%8D%8F%E4%BD%9C%E5%BC%80%E5%8F%91%E5%B7%A5%E4%BD%9C%E6%B5%81%EF%BC%88git-flow%EF%BC%89"><span class="toc-number">3.1.</span> <span class="toc-text">多人协作开发工作流（git flow）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%9A%E4%BA%BA%E5%8D%8F%E5%90%8C%E5%BC%80%E5%8F%91%E5%8A%9F%E8%83%BD"><span class="toc-number">3.2.</span> <span class="toc-text">多人协同开发功能</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A8%A1%E6%8B%9F%E5%A4%9A%E4%BA%BA%E5%8D%8F%E4%BD%9C%E5%9C%BA%E6%99%AF"><span class="toc-number">3.2.1.</span> <span class="toc-text">模拟多人协作场景</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%89%88%E6%9C%AC%E6%A0%87%E7%AD%BE%E5%91%BD%E5%90%8D"><span class="toc-number">3.2.2.</span> <span class="toc-text">版本标签命名</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%82%80%E8%AF%B7%E6%88%90%E5%91%98"><span class="toc-number">3.2.3.</span> <span class="toc-text">邀请成员</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%88%90%E5%91%98%E6%A8%A1%E6%8B%9F"><span class="toc-number">3.2.4.</span> <span class="toc-text">成员模拟</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81review"><span class="toc-number">3.2.5.</span> <span class="toc-text">代码review</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B5%8B%E8%AF%95%E9%A2%84%E5%8F%91%E5%B8%83"><span class="toc-number">3.2.6.</span> <span class="toc-text">测试预发布</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%99%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE%E8%B4%A1%E7%8C%AE%E4%BB%A3%E7%A0%81"><span class="toc-number">3.3.</span> <span class="toc-text">给开源项目贡献代码</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#git%E5%85%B6%E4%BB%96%E6%8B%93%E5%B1%95"><span class="toc-number">4.</span> <span class="toc-text">git其他拓展</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE"><span class="toc-number">4.1.</span> <span class="toc-text">配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%8D%E5%AF%86%E7%99%BB%E5%BD%95"><span class="toc-number">4.2.</span> <span class="toc-text">免密登录</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#gitignore%E5%BF%BD%E7%95%A5%E6%96%87%E4%BB%B6"><span class="toc-number">4.3.</span> <span class="toc-text">gitignore忽略文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%BB%E5%8A%A1%E7%AE%A1%E7%90%86%E7%9B%B8%E5%85%B3"><span class="toc-number">4.4.</span> <span class="toc-text">任务管理相关</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#issues"><span class="toc-number">4.4.1.</span> <span class="toc-text">issues</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#wiki"><span class="toc-number">4.4.2.</span> <span class="toc-text">wiki</span></a></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/notes/dockerNotes/" title="Docker备忘笔记"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Docker备忘笔记"/></a><div class="content"><a class="title" href="/notes/dockerNotes/" title="Docker备忘笔记">Docker备忘笔记</a><time datetime="2024-04-06T13:17:09.000Z" title="发表于 2024-04-06 21:17:09">2024-04-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/mysqlInstall/" title="mysql压缩包方式本地安装"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="mysql压缩包方式本地安装"/></a><div class="content"><a class="title" href="/notes/mysqlInstall/" title="mysql压缩包方式本地安装">mysql压缩包方式本地安装</a><time datetime="2024-01-03T05:33:33.000Z" title="发表于 2024-01-03 13:33:33">2024-01-03</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/PdfView/" title="基于pdf.js的前后端分离式PDF文件预览实现"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="基于pdf.js的前后端分离式PDF文件预览实现"/></a><div class="content"><a class="title" href="/notes/PdfView/" title="基于pdf.js的前后端分离式PDF文件预览实现">基于pdf.js的前后端分离式PDF文件预览实现</a><time datetime="2023-08-06T02:18:26.000Z" title="发表于 2023-08-06 10:18:26">2023-08-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/electronVue/" title="Electron+Vue项目搭建"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Electron+Vue项目搭建"/></a><div class="content"><a class="title" href="/notes/electronVue/" title="Electron+Vue项目搭建">Electron+Vue项目搭建</a><time datetime="2023-05-14T02:36:59.000Z" title="发表于 2023-05-14 10:36:59">2023-05-14</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/chunkFile/" title="基于SpringBoot与Vue的大文件分片上传与流式下载"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="基于SpringBoot与Vue的大文件分片上传与流式下载"/></a><div class="content"><a class="title" href="/notes/chunkFile/" title="基于SpringBoot与Vue的大文件分片上传与流式下载">基于SpringBoot与Vue的大文件分片上传与流式下载</a><time datetime="2023-05-13T13:57:28.000Z" title="发表于 2023-05-13 21:57:28">2023-05-13</time></div></div></div></div></div></div></main><footer id="footer" style="background: -#484847"><div id="footer-wrap"><div class="copyright">&copy;2023 - 2024 By Lenl</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">Hi, welcome to my blog !</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><div class="js-pjax"><script>function loadValine () {
  function initValine () {
    const valine = new Valine(Object.assign({
      el: '#vcomment',
      appId: 'dBlOeCLNhBxbSdZO44fRKdBa-gzGzoHsz',
      appKey: 'DCSQoDhPl0UOF7Ix9Imdfd9X',
      avatar: 'monsterid',
      serverURLs: '',
      emojiMaps: "",
      path: window.location.pathname,
      visitor: false
    }, null))
  }

  if (typeof Valine === 'function') initValine() 
  else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
}

if ('Valine' === 'Valine' || !false) {
  if (false) btf.loadComment(document.getElementById('vcomment'),loadValine)
  else setTimeout(loadValine, 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script></div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div class="no-result" id="local-search-results"></div><div id="local-search-stats-wrap"></div></div></div><div id="search-mask"></div><script src="/js/search/local-search.js"></script></div></div></body></html>